//////////////////////////////////////////////////////////////////
// (c) Copyright 1998-2002 by Jeongnim Kim
//
//   National Center for Supercomputing Applications &
//   Materials Computation Center
//   University of Illinois, Urbana-Champaign
//   Urbana, IL 61801
//   e-mail: jnkim@ncsa.uiuc.edu
//   Tel:    217-244-6319 (NCSA) 217-333-3324 (MCC)
//
// Supported by 
//   National Center for Supercomputing Applications, UIUC
//   Materials Computation Center, UIUC
//   Department of Physics, Ohio State University
//   Ohio Supercomputer Center
//////////////////////////////////////////////////////////////////
// -*- C++ -*-
#ifndef OHMMS_EIGENSPACEDIMENSION_H
#define OHMMS_EIGENSPACEDIMENSION_H
/****************************************************************************
 * struct EigenSpaceDimension is a container for parameters
 * that determine the type of eigen value problem.
 * EigenSpaceDimension()              // do nothing constructor
 * EigenSpaceDimension(int n)         // n eigen states for n x n matrix
 * EigenSpaceDimension(int n, int m ) // m eigen states for n x n matrix
 * EigenSpaceDimension(int n, int i0, int m ) 
 *                   // m eigen states for n x n matrix, i0 is the lowest state.
 * EigenSpaceDimension(int n, int m, double x) 
 *                   // m eigen states for n x n matrix, x is the reference value.
 * EigenSpaceDimension(int n, double xmin, double xmax) 
 *                   // eigen states for n x n matrix, xmin <= eigen values < xmax
 * set functions with the correponding argument lists of the constructors
 * can be used to reset the problems.
 * set functions will set the EigMode.
 * EigenSolvers should implement or set the parameters according to EigMode
 ****************************************************************************/
 

struct EigenSpaceDimension {

  enum EigenSpectrum {ALL, SHIFTED, MIN, MAX, INSIDE};

  EigenSpectrum EigMode;
  int N, M;
  int First, Last; // index for the first and last eigen values of interest
                   // WARNING: using 1 -- N base for fortran libraries
  double MinE, MaxE, RefE;
  //vector<double> EigVal;

  EigenSpaceDimension():First(-1),Last(-1), RefE(0), N(0), M(0) { }
  EigenSpaceDimension(int n) { set(n);}
  EigenSpaceDimension(int n, int m) { set(n,m);}
  EigenSpaceDimension(int n, int i0, int m) { set(n,i0,m);}
  EigenSpaceDimension(int n, int m, double x) { set(n,m,x);}
  EigenSpaceDimension(int n, int m, double xmin, double xmax) {
    set(n, m, xmin, xmax);
  }

  inline void set() { checkMode();}
  inline void set(int n) { 
    N = n; M = n; 
    checkMode();
  }
  inline void set(int n, int m) { 
    N = n; 
    if(n >=m)  M = m;  
    else       M = n;        // ignore the incorrect input
    checkMode();
  }

  inline void set(int n, int i0, int m) { 
    N = n;                        // basis dimension
    First = i0; 
    if(m <= 0) {
      Last = N; // if negative, Last is the maximum eigen values
      M = Last - First + 1;
    } else {
      Last = First+m-1; // first and last indices
      if(Last <= N) M = m; 
      else {
        Last = N;
        M = Last-First+1;
      }
    }
    checkMode();
  }

  inline void set(int n, int m, double x) {
    N = n; M = m; First = -1; Last = -1;
    RefE = x;
    MinE = x-1; MaxE = x+1;  // +- 1eV window
    EigMode = SHIFTED;
    checkMode();
  }
  inline void set(int n, int m, double x0, double y0) {
    N = n; M = m; First = -1; Last = -1; 
    MinE = x0; MaxE = y0; RefE = (x0+y0)*0.5e0;
    EigMode = SHIFTED;
    checkMode();
  }
 
  void checkMode() {
    if(N == M) { 
      First = 1;
      Last = M;
      EigMode = ALL; // All the eigen values are calculated
    } else {
      if(EigMode != SHIFTED) {
        if(First < 0) First = 1; 
        if(Last < 0)  Last = M;
        if(First == 1){
          EigMode = MIN; 
        } else {
          if(Last == N) EigMode = MAX;
          else          EigMode = INSIDE;
        }
      }
    }
    //EigVal.resize(N);
  }
};
#endif

/***************************************************************************
 * $RCSfile: EigenSpaceDimension.h,v $   $Author: jnkim $
 * $Revision: 1.1.1.1 $   $Date: 2004/07/23 21:04:02 $
 * $Id: EigenSpaceDimension.h,v 1.1.1.1 2004/07/23 21:04:02 jnkim Exp $ 
 ***************************************************************************/

